(function($){    
    $.fn.searchable = function(config) {    
        var $searchCtn = $(this),
            $searchBox,
            $searchBtn,
            $cancelSearchBtn,
            //搜索范围列表. 
            searchTypeOptions = config['searchTypeOptions'], 
            $searchTypeOptionsWrapper = null,
            isShowTypeOptions = !Type.isUndefined(config['searchTypeOptions']) && config['searchTypeOptions'].length,
            //事件处理器.
            onSearchHandler = config['onSearch'], 
            onKeyupHandler = config['onKeyup'],
            onCancelSearchHandler = config['onCancelSearch'],
            onAdvancedSearchHandler = config['onAdvancedSearch'];
        
        //搜索框样式控制.
        $searchCtn.addClass('searchCtn');        
        if(config['theme']){
            $searchCtn.addClass(config['theme']);    
        }
        $searchCtn.style(config['style']);
        
        //搜索框.
        $searchBox = $searchCtn.find('.searchBox');
        if(!$searchBox.length){
            $searchBox = $('<input class="searchBox" />').appendTo($searchCtn);
        }
        $searchBox.style(config['boxStyle']);
        $searchBox.attr('placeholder', config['placeholder'] || '搜索...');
        $searchBox.keydown(function(e) {
            if (e.keyCode === 13) {//enter
                if(Type.isFunction(onSearchHandler)){
                    if(isShowTypeOptions){                    
                        $searchTypeOptionsWrapper.hide();
                        onSearchHandler($searchBox.val().trim(), $searchTypeOptionsWrapper.find('.current').attr('val'), $searchBox);
                    } else {
                        onSearchHandler($searchBox.val().trim(), null, $searchBox);
                    }
                }                
                return false;   //return false避免某些浏览器回车提交事件.
            } else if (e.keyCode === 40) {//down
                if(isShowTypeOptions){
                    var currentTypeOption = $searchTypeOptionsWrapper.find('.current').removeClass('current'), 
                        nextTypeOption = currentTypeOption.next();
                    if (nextTypeOption.length) {
                        nextTypeOption.addClass('current');
                    } else {
                        currentTypeOption.parent().find(':first-child').addClass('current');
                    }
                }
            } else if (e.keyCode === 38) {//up
                if(isShowTypeOptions){
                    var currentTypeOption = $searchTypeOptionsWrapper.find('.current').removeClass('current'), 
                        prevTypeOption = currentTypeOption.prev();
                    if (prevTypeOption.length) {
                        prevTypeOption.addClass('current');
                    } else {
                        currentTypeOption.parent().find(':last-child').addClass('current');
                    }
                }                    
            } else {
                if(isShowTypeOptions){
                    $searchTypeOptionsWrapper.show('fast');
                }
            }                
        }).keyup(function(){
            if(Type.isFunction(onKeyupHandler)){
                onKeyupHandler($searchBox.val().trim());
            }
        }).bind('click focus', function(e) {
            var searchText = $.trim($(this).val());
            if (searchText && isShowTypeOptions) {
                $searchTypeOptionsWrapper.show('fast');
            }
            e.stopPropagation();
        });
        
        //取消搜索按钮.
        $cancelSearchBtn = $searchCtn.find('.cancelSearchBtn'); 
        if(!$cancelSearchBtn.length){
            $cancelSearchBtn = $('<button class="cancelSearchBtn"></button>').appendTo($searchCtn);
        }
        $cancelSearchBtn.bind('click', function() {
            $searchBox.val('');
            if(Type.isFunction(onCancelSearchHandler)){
                onCancelSearchHandler($searchBox);
            }
        });
            
        //高级搜索按钮
        if(config['isShowAdvancedSearchBtn'] === true){
            var $advancedSearchTrigger = $('<div title="Advanced Search" class="advancedSearchTrigger"></div>'); 
            $searchCtn.append($advancedSearchTrigger);        
            $searchCtn.find('.cancelSearchBtn').css('right', '28px');
            $advancedSearchTrigger.bind({
                'click' : function(){
                    if(onAdvancedSearchHandler){
                        onAdvancedSearchHandler();
                    }     
                }
            });        
        }
    
        //搜索按钮.
        if(config['isShowSearchBtn'] !== false){
            $searchBtn = $searchCtn.find('.searchBtn');
            if(!$searchBtn.length){
                $searchCtn.append('<button class="searchBtn">{0}</button>'.format( config['searchBtnText'] || '搜索' ));
            }
            $searchBtn.click(function(e){
                if(Type.isFunction(onSearchHandler)){
                    onSearchHandler($searchBox.val().trim(), null, $searchBox);
                }
            });
        }
                    
        //搜索范围列表.        
        if(isShowTypeOptions){
            $searchTypeOptionsWrapper = $searchCtn.find('.searchTypeOptionsWrapper');   
            if(!$searchTypeOptionsWrapper.length){        
                $searchTypeOptionsWrapper = $('<ul class="searchTypeOptionsWrapper"></ul>');
            }
            for(var i=0, searchTypeOptionsLen = searchTypeOptions.length; i < searchTypeOptionsLen; i++){
                var $searchOptionItem = $('<li val="{0}" class="searchOptionItem">{1}</li>'.format(
                    searchTypeOptions[i]['val'], 
                    searchTypeOptions[i]['text']
                ));
                if (i === 0) {
                    $searchOptionItem.addClass('current');
                }
                if (i === searchTypeOptionsLen - 1) {
                    $searchOptionItem.addClass('last');
                }
                $searchOptionItem.appendTo($searchTypeOptionsWrapper);
            }
            $searchTypeOptionsWrapper.appendTo($searchCtn);
            //click search type.    
            $searchTypeOptionsWrapper.find('.searchOptionItem').bind('click',function(){
                $(this).addClass('current').siblings().removeClass('current');
                if(Type.isFunction(onSearchHandler)){
                    onSearchHandler($searchBox.val().trim(), $(this).attr('val'), $searchBox);
                }            
            });
            //hide dropdown list when click document.
            $(document.body).click(function(){
                if(isShowTypeOptions) {
                    $searchTypeOptionsWrapper.hide();
                }
            });           
        }    
    };
})($);